<!-- AdvancedCellTextButtonWithSearch.vue -->

<template>
  <div class="advanced-cell-text-button-with-search" :style="columnWidth ? { width: columnWidth } : {}">
    <input
        type="text"
        :value="displayValue"
        @input="handleInput"
        @focus="$emit('focus', $event)"
        @blur="$emit('blur', $event)"
        class="text-input"
    />
    <button @click="openPopup" class="button">...</button>

    <!-- 弹出窗体 -->
    <div v-if="showPopup" class="popup">
      <div class="popup-content">
        <h3>搜索和选择</h3>
        <div class="search-bar">
          <input
              v-model="searchQuery"
              placeholder="搜索..."
              class="search-input"
              @keyup.enter="handleSearch"
          />
          <button @click="handleSearch" class="search-button">搜索</button>
        </div>

        <div v-if="isLoading" class="loading">加载中...</div>

        <!-- 搜索结果表格 -->
        <div v-else-if="searchResults.length" class="table-container">
          <table class="search-results">
            <thead>
            <!-- ... 表头内容保持不变 ... -->
            </thead>
            <tbody>
            <tr v-for="item in paginatedResults"
                :key="getItemKey(item)"
                @click="handleRowClick(item)"
                @dblclick="handleRowDoubleClick(item)"
                :class="{ 'selected': isItemSelected(item) }">
              <td v-for="field in visibleFields" :key="field">
                {{ item[field] }}
              </td>
              <td v-if="isMultiSelect">
                <input
                    type="checkbox"
                    :checked="isItemSelected(item)"
                    @change="toggleItemSelection(item, $event)"
                    @click.stop
                >
              </td>
            </tr>
            </tbody>
          </table>
        </div>
        <div v-else-if="searchPerformed" class="no-results">没有找到匹配的结果</div>

        <!-- 分页控件 -->
        <div v-if="searchResults.length" class="pagination">
          <span>{{ (currentPage - 1) * pageSize + 1 }}-{{ Math.min(currentPage * pageSize, totalItems) }} 共 {{ totalItems }} 条</span>
          <button @click="prevPage" :disabled="currentPage === 1">上一页</button>
          <span>{{ currentPage }} / {{ totalPages }}</span>
          <button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
          <select v-model="pageSize" @change="handlePageSizeChange">
            <option :value="10">10 条/页</option>
            <option :value="20">20 条/页</option>
            <option :value="30">30 条/页</option>
          </select>
        </div>

        <!-- 字段选择器 (只在多选模式下显示) -->
        <div v-if="isMultiSelect" class="field-selector">
          <h4>显示字段：</h4>
          <div class="field-options">
            <label v-for="field in allFields" :key="field" class="field-option">
              <input
                  type="checkbox"
                  :checked="visibleFields.includes(field)"
                  @change="toggleField(field)"
              >
              {{ field }}
            </label>
          </div>
        </div>

        <!-- 已选项目 (只在多选模式下显示) -->
        <div v-if="isMultiSelect && selectedItems.length" class="selected-items">
          <h4>已选择项目</h4>
          <ul>
            <li v-for="item in selectedItems" :key="getItemKey(item)">
              {{ getItemDisplayValue(item) }}
              <button @click="removeSelectedItem(item)" class="remove-button">移除</button>
            </li>
          </ul>
        </div>

        <div class="popup-buttons">
          <button @click="confirmSelection" class="confirm-button">确认</button>
          <button @click="closePopup" class="cancel-button">取消</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue';

export default {
  name: 'AdvancedCellTextButtonWithSearch',
  props: {
    modelValue: String,
    columnWidth: String,
    searchObj: {
      type: Object,
      required: true,
      validator: (obj) => {
        return obj && obj.url && obj.keyField && obj.showField && obj.token && obj.sourceField && obj.destField;
      }
    }
  },
  emits: ['update:modelValue', 'focus', 'blur', 'input'],
  setup(props, { emit }) {

    const tempSelectedItem = ref(null); // 用于单选模式的临时选择
    const isMultiSelect = computed(() => props.searchObj.isMultiSelect === true);
    const sourceFields = computed(() => props.searchObj.sourceField.split(';'));
    const destFields = computed(() => props.searchObj.destField.split(';'));
    const showPopup = ref(false);
    const searchQuery = ref('');
    const searchResults = ref([]);
    const selectedItems = ref([]);
    const currentPage = ref(1);
    const pageSize = ref(10);
    const totalItems = ref(0);
    const sortField = ref('');
    const sortOrder = ref('asc');
    const isLoading = ref(false);
    const searchPerformed = ref(false);

    const allFields = computed(() => props.searchObj.showField.split(';'));
    const visibleFields = ref(allFields.value);
    const keyFields = computed(() => props.searchObj.keyField.split(';'));

    const paginatedResults = computed(() => searchResults.value);

    const totalPages = computed(() => Math.ceil(totalItems.value / pageSize.value));

    const getItemKey = (item) => {
      return keyFields.value.map(field => item[field]).join('_');
    };

    const getItemDisplayValue = (item) => {
      return visibleFields.value.map(field => `${field}: ${item[field]}`).join(', ');
    };

    const isItemSelected = (item) => {
      if (isMultiSelect.value) {
        return selectedItems.value.some(selectedItem => getItemKey(selectedItem) === getItemKey(item));
      } else {
        return tempSelectedItem.value && getItemKey(tempSelectedItem.value) === getItemKey(item);
      }
    };

    const displayValue = computed(() => {
      if (selectedItems.value.length === 0) return props.modelValue || '';
      if (!isMultiSelect.value) {
        return selectedItems.value[0][sourceFields.value[0]] || props.modelValue || '';
      }
      return selectedItems.value.map(item => item[sourceFields.value[0]]).join(', ') || props.modelValue || '';
    });

    const handleInput = (event) => {
      emit('update:modelValue', event.target.value);
      emit('input', event.target.value);
    };

    const openPopup = () => {
      showPopup.value = true;
      searchQuery.value = '';
      searchResults.value = [];
      searchPerformed.value = false;
      if (!isMultiSelect.value) {
        selectedItems.value = [];
      }
    };

    const closePopup = () => {
      showPopup.value = false;
      if (!isMultiSelect.value) {
        tempSelectedItem.value = null;
      }
    };

    const handleSearch = async () => {
      if (!props.searchObj || !props.searchObj.url) {
        console.error('searchObj or searchObj.url is undefined');
        return;
      }

      isLoading.value = true;
      searchPerformed.value = true;
      try {
        const fullUrl = `${props.searchObj.url}&query=${encodeURIComponent(searchQuery.value)}&pageNo=${currentPage.value}&pageSize=${pageSize.value}`;
        const headers = new Headers({
          'X-Access-Token': props.searchObj.token
        });

        const response = await fetch(fullUrl, {
          method: 'GET',
          headers: headers
        });

        if (!response.ok) {
          throw new Error('搜索请求失败');
        }
        const data = await response.json();

        if (data.success && data.result) {
          searchResults.value = data.result.records;
          currentPage.value = data.result.current;
          totalItems.value = data.result.total;
          pageSize.value = data.result.size;
        } else {
          throw new Error(data.message || '搜索失败');
        }
      } catch (error) {
        console.error('搜索出错:', error);
        searchResults.value = [];
        totalItems.value = 0;
      } finally {
        isLoading.value = false;
      }
    };
    const handleRowDoubleClick = (item) => {
      if (!isMultiSelect.value) {
        tempSelectedItem.value = item;
        confirmSelection();
      }
    };
    const sortBy = (field) => {
      if (sortField.value === field) {
        sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';
      } else {
        sortField.value = field;
        sortOrder.value = 'asc';
      }
      searchResults.value.sort((a, b) => {
        if (a[field] < b[field]) return sortOrder.value === 'asc' ? -1 : 1;
        if (a[field] > b[field]) return sortOrder.value === 'asc' ? 1 : -1;
        return 0;
      });
    };

    const toggleField = (field) => {
      const index = visibleFields.value.indexOf(field);
      if (index > -1) {
        visibleFields.value.splice(index, 1);
      } else {
        visibleFields.value.push(field);
      }
    };

    const toggleItemSelection = (item, event) => {
      if (isMultiSelect.value) {
        const index = selectedItems.value.findIndex(selectedItem => getItemKey(selectedItem) === getItemKey(item));
        if (index === -1) {
          selectedItems.value.push(item);
        } else {
          selectedItems.value.splice(index, 1);
        }
        // 防止触发行点击事件
        event.stopPropagation();
      } else {
        tempSelectedItem.value = item;
      }
    };

    const handleRowClick = (item) => {
      if (!isMultiSelect.value) {
        toggleItemSelection(item);
      }
    };

    const removeSelectedItem = (item) => {
      const index = selectedItems.value.findIndex(selectedItem => getItemKey(selectedItem) === getItemKey(item));
      if (index !== -1) {
        selectedItems.value.splice(index, 1);
      }
    };

    const confirmSelection = () => {
      if (isMultiSelect.value && selectedItems.value.length === 0) {
        console.warn('No items selected');
        return;
      }
      if (!isMultiSelect.value && !tempSelectedItem.value) {
        console.warn('No item selected');
        return;
      }

      let destData;
      if (isMultiSelect.value) {
        destData = selectedItems.value.map(item => {
          const itemData = {};
          destFields.value.forEach((field, index) => {
            const sourceField = sourceFields.value[index];
            itemData[field] = item[sourceField] || '';
          });
          return itemData;
        });
      } else {
        destData = {};
        destFields.value.forEach((field, index) => {
          const sourceField = sourceFields.value[index];
          destData[field] = tempSelectedItem.value[sourceField] || '';
        });
      }
      emit('update:modelValue', JSON.stringify(destData));
      emit('input', JSON.stringify(destData));
      closePopup();
    };

    const prevPage = () => {
      if (currentPage.value > 1) {
        currentPage.value--;
        handleSearch();
      }
    };

    const nextPage = () => {
      if (currentPage.value < totalPages.value) {
        currentPage.value++;
        handleSearch();
      }
    };

    const handlePageSizeChange = () => {
      currentPage.value = 1;
      handleSearch();
    };

    watch(() => props.modelValue, (newValue) => {
      if (newValue) {
        try {
          let parsedValue;
          if (typeof newValue === 'string' && (newValue.startsWith('{') || newValue.startsWith('['))) {
            parsedValue = JSON.parse(newValue);
          } else {
            parsedValue = { [destFields.value[0]]: newValue };
          }

          if (Array.isArray(parsedValue)) {
            selectedItems.value = parsedValue.map(item => {
              const result = {};
              sourceFields.value.forEach((sourceField, index) => {
                result[sourceField] = item[destFields.value[index]] || '';
              });
              return result;
            });
          } else {
            selectedItems.value = [parsedValue].map(item => {
              const result = {};
              sourceFields.value.forEach((sourceField, index) => {
                result[sourceField] = item[destFields.value[index]] || '';
              });
              return result;
            });
          }
        } catch (e) {
          console.error('无法解析 modelValue:', e);
          selectedItems.value = [{ [sourceFields.value[0]]: newValue }];
        }
      } else {
        selectedItems.value = [];
      }
    }, { immediate: true });

    return {
      showPopup,
      searchQuery,
      searchResults,
      selectedItems,
      currentPage,
      totalPages,
      pageSize,
      totalItems,
      sortField,
      sortOrder,
      isLoading,
      searchPerformed,
      visibleFields,
      allFields,
      paginatedResults,
      openPopup,
      closePopup,
      handleInput,
      handleSearch,
      getItemKey,
      getItemDisplayValue,
      isItemSelected,
      toggleItemSelection,
      removeSelectedItem,
      confirmSelection,
      prevPage,
      nextPage,
      sortBy,
      toggleField,
      sourceFields,
      destFields,
      handlePageSizeChange,
      isMultiSelect,
      handleRowClick,
      handleRowDoubleClick,
      tempSelectedItem,
      displayValue
    };
  }
}
</script>

<style scoped>

.search-results tr.selected {
  background-color: #e6f7ff;
}

.search-results tr:hover {
  background-color: #f5f5f5;
  cursor: pointer;
}
.advanced-cell-text-button-with-search {
  display: flex;
  align-items: center;
  height: 100%;
  box-sizing: border-box;
}

.text-input {
  flex-grow: 1;
  min-width: 0;
  padding: 2px 4px;
  border: none;
  background: transparent;
  font-size: inherit;
  line-height: inherit;
  height: 100%;
}

.button {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  padding: 0;
  margin-left: 2px;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
  border-radius: 2px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
}

.popup {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.popup-content {
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  width: 80%;
  max-width: 800px;
  max-height: 80vh;
  overflow-y: auto;
}

.search-bar {
  display: flex;
  margin-bottom: 10px;
}

.search-input {
  flex-grow: 1;
  padding: 5px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.search-button {
  margin-left: 5px;
  padding: 5px 10px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.loading {
  text-align: center;
  padding: 20px;
}

.table-container {
  max-height: 300px;
  overflow-y: auto;
}

.search-results {
  width: 100%;
  border-collapse: collapse;
}

.search-results th, .search-results td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

.search-results th {
  background-color: #f2f2f2;
  position: sticky;
  top: 0;
}

.sort-button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0 5px;
}

.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 10px;
}

.pagination button, .pagination select {
  margin: 0 5px;
  padding: 5px 10px;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
  border-radius: 4px;
  cursor: pointer;
}

.field-selector {
  margin-top: 10px;
}

.field-options {
  display: flex;
  flex-wrap: wrap;
}
.field-option {
  margin-right: 10px;
  margin-bottom: 5px;
}

.selected-items {
  margin-top: 10px;
}

.selected-items ul {
  list-style-type: none;
  padding: 0;
}

.selected-items li {
  margin-bottom: 5px;
}

.remove-button {
  margin-left: 5px;
  padding: 2px 5px;
  background-color: #f44336;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.popup-buttons {
  margin-top: 20px;
  text-align: right;
}

.confirm-button, .cancel-button {
  padding: 8px 15px;
  margin-left: 10px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.confirm-button {
  background-color: #4CAF50;
  color: white;
}

.cancel-button {
  background-color: #f44336;
  color: white;
}

.no-results {
  text-align: center;
  padding: 20px;
  color: #666;
}
</style>
